//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Pivot;

namespace OpenLS.Spreadsheet
{
    public class SheetView: IOfficeXmlSerializable, INotifyPropertyChanged
    {
        public SheetView(Sheet sheet)
        {
            _sheet = sheet;
        }
        internal Sheet _sheet;
        private bool _showZeros = true;

        public bool ZerosVisible
        {
            get { return _showZeros; }
            set
            {
                _showZeros = value; NotifyPropertyChanged("ZerosVisible");
            }
        }

        private bool _windowProtection;

        public bool WindowProtection
        {
            get { return _windowProtection; }
            set
            {
                _windowProtection = value; NotifyPropertyChanged("WindowProtection");
            }
        }

        private bool _showFormulas = true;

        public bool FormulasVisible
        {
            get { return _showFormulas; }
            set
            {
                _showFormulas = value; NotifyPropertyChanged("FormulasVisible");
            }
        }

        private bool _tabSelected;

        public bool TabSelected
        {
            get { return _tabSelected; }
            set { _tabSelected = value; }
        }

        private bool _rightToLeft;

        public bool RightToLeft
        {
            get { return _rightToLeft; }
            set
            {
                _rightToLeft = value;
                NotifyPropertyChanged("RightToLeft");
            }
        }

        private bool _showRuler = true;

        public bool RulerVisible
        {
            get { return _showRuler; }
            set
            {
                _showRuler = value;
                NotifyPropertyChanged("RulerVisible");
            }
        }

        internal const string GridLinesVisiblePropertyName = "GridLinesVisible";
        public bool GridLinesVisible
        {
            get { return _showGridLines; }
            set
            {
                if (_showGridLines == value)
                    return;
                _showGridLines = value;
                NotifyPropertyChanged(GridLinesVisiblePropertyName);
            }
        }
        private bool _showGridLines = true;

        private int _zoomScalePageLayoutView;

        public int ZoomScalePageLayoutView
        {
            get
            {
                if (ZoomScalePageLayoutView == 0)
                    return ZoomScale;
                return _zoomScalePageLayoutView;
            }
            set
            {
                _zoomScalePageLayoutView = value;
                NotifyPropertyChanged("ZoomScalePageLayoutView");
            }
        }

        private int _zoomScale = 100;

        public int ZoomScale
        {
            get { return _zoomScale; }
            set
            {
                _zoomScale = value;
                NotifyPropertyChanged("ZoomScale");
            }
        }
        private int _zoomScaleNormal;

        public int ZoomScaleNormal
        {
            get
            {
                if (ZoomScale == 0)
                    return ZoomScale;
                return _zoomScaleNormal;
            }
            set
            {
                _zoomScaleNormal = value;
                NotifyPropertyChanged("ZoomScaleNormal");
            }
        }


        private bool _showWhiteSpace = true;

        public bool WhiteSpaceVisible
        {
            get { return _showWhiteSpace; }
            set
            {
                _showWhiteSpace = value;
                NotifyPropertyChanged("WhiteSpaceVisible");
            }
        }




        private int _zoomScaleSheetLayoutView;

        public int ZoomScaleSheetLayoutView
        {
            get
            {
                if (_zoomScaleSheetLayoutView == 0)
                    return _zoomScale;
                return _zoomScaleSheetLayoutView;
            }
            set
            {
                _zoomScaleSheetLayoutView = value;
                NotifyPropertyChanged("ZoomScaleSheetLayoutView");
            }
        }

        private int _workbookViewId;

        internal int WorkbookViewId
        {
            get { return _workbookViewId; }
            set { _workbookViewId = value; }
        }



        private SheetViewType _viewType;

        public SheetViewType ViewType
        {
            get { return _viewType; }
            set
            {
                _viewType = value;
                NotifyPropertyChanged("ViewType");
            }
        }

        private bool _showRowColumnHeaders = true;

        public bool RowColumnHeadersVisible
        {
            get { return _showRowColumnHeaders; }
            set
            {
                if (_showRowColumnHeaders == value)
                    return;
                _showRowColumnHeaders = value;
                NotifyPropertyChanged("RowColumnHeadersVisible");
            }
        }

        private InternalSelection _topLeftSelection;
        internal InternalSelection TopLeftSelection
        {
            get { return _topLeftSelection; }
        }
        private InternalSelection _topRightSelection;
        internal InternalSelection TopRightSelection
        {
            get { return _topRightSelection; }
        }
        private InternalSelection  _bottomLeftSelection;
        internal InternalSelection BottomLeftSelection
        {
            get { return _bottomLeftSelection; }
        }
        private InternalSelection _bottomRightSelection;
        internal InternalSelection BottomRightSelection
        {
            get { return _bottomRightSelection; }
        }






        private bool _defaultGridColor = true;

        public bool DefaultGridColor
        {
            get { return _defaultGridColor; }
            set
            {
                _defaultGridColor = value;
                NotifyPropertyChanged("DefaultGridColor");
            }
        }


        private bool _showOutlineSymbols;

        public bool OutlineSymbolsVisible
        {
            get { return _showOutlineSymbols; }
            set
            {
                _showOutlineSymbols = value;
                NotifyPropertyChanged("OutlineSymbolsVisible");
            }
        }



        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        internal string _topLeftCache;


        private ExtensionElement _extension;

        public ExtensionElement Extension
        {
            get { return _extension; }
            set { _extension = value; }
        }


        private Pane _pane;

        public Pane Pane
        {
            get
            {
                return _pane;
            }
            set { _pane = value; NotifyPropertyChanged("Pane"); }
        }

        internal Range _selection;

        internal Range Selection
        {
            get { return _selection; }
            set { _selection = value; }
        }

        private CellAddress? activeCell;
        private PivotSelection _pivotSelection;
        internal Pivot.PivotTableDefinition PivotTable
        {
            get
            {
                if (_pivotSelection != null)
                    return _pivotSelection.Definition;
                return null;
            }
        }

        internal CellAddress? ActiveCellPosition
        {
            get { return activeCell; }
            set { activeCell = value; }
        }




        #endregion


        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("sheetView"))
            {
                _windowProtection = c.GetOptionalBoolean("windowProtection", false);
                FormulasVisible = c.GetOptionalBoolean("showFormulas", true);
                GridLinesVisible = c.GetOptionalBoolean("showGridLines", true);
                RowColumnHeadersVisible = c.GetOptionalBoolean("showRowColHeaders", true);
                TabSelected = c.GetBoolean("tabSelected");
                ZerosVisible = c.GetOptionalBoolean("showZeros", true);
                RightToLeft = c.GetOptionalBoolean("rightToLeft", false);
                RulerVisible = c.GetOptionalBoolean("showRuler", true);
                OutlineSymbolsVisible = c.GetOptionalBoolean("showOutlineSymbols", true);
                DefaultGridColor = c.GetOptionalBoolean("defaultGridColor", true);
                WhiteSpaceVisible = c.GetOptionalBoolean("showWhiteSpace", true);
                ViewType = c.GetOptionalEnum("view", SheetViewType.Normal);
                ZoomScale = c.GetOptionalInteger("zoomScale", 100);
                ZoomScaleNormal = c.GetOptionalInteger("zoomScaleNormal", 0);
                _zoomScaleSheetLayoutView = c.GetOptionalInteger("zoomScaleSheetLayoutView", 0);
                _zoomScalePageLayoutView = c.GetOptionalInteger("zoomScalePageLayoutView", 0);
                _workbookViewId = c.GetOptionalInteger("workbookViewId", 0);
                _topLeftCache = c.GetOptionalString("topLeftCell");
                //\\reader.ReadStartElement();
                //\\c.PassAttributes(); 
                Pane = c.ReadOptionalElement<Pane>("pane");
                
                InternalSelection s = c.ReadOptionalElement<InternalSelection>("selection");
                while (s != null)
                {
                    switch (s.Pane)
                    {
                        case PaneType.TopLeft: _topLeftSelection = s; break;
                        case PaneType.TopRight: _topRightSelection = s; break;
                        case PaneType.BottomLeft: _bottomLeftSelection = s; break;
                        case PaneType.BottomRight: _bottomRightSelection = s; break;
                        default: throw new NotSupportedException();

                    }
                    s = c.ReadOptionalElement<InternalSelection>("selection");
                }
                if (BottomRightSelection != null)
                {
                    if (TopLeftSelection == null)
                        _topLeftSelection = new InternalSelection();
                    if (TopRightSelection == null)
                        _topRightSelection = new InternalSelection();
                    if (BottomLeftSelection == null)
                        _bottomLeftSelection = new InternalSelection();
                }
                if (TopRightSelection == null)
                {
                    if (TopLeftSelection == null)
                        _topLeftSelection = new InternalSelection();
                }
                if (BottomLeftSelection == null)
                {
                    if (TopLeftSelection == null)
                        _topLeftSelection = new InternalSelection();
                }
                _pivotSelection = c.ReadOptionalElement<PivotSelection>("pivotSelection");
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("sheetView"))
            {
                c.SetOptionalBoolean("windowProtection", _windowProtection, false);
                c.SetOptionalBoolean("showFormulas", FormulasVisible, true);
                c.SetOptionalBoolean("showGridLines", GridLinesVisible, true);
                c.SetOptionalBoolean("showRowColHeaders", RowColumnHeadersVisible, true);
                c.SetBoolean("tabSelected", TabSelected);
                c.SetOptionalBoolean("showZeros", ZerosVisible, true);
                c.SetOptionalBoolean("rightToLeft", RightToLeft, false);
                c.SetOptionalBoolean("showRuler", RulerVisible, true);
                c.SetOptionalBoolean("showOutlineSymbols", OutlineSymbolsVisible, true);
                c.SetOptionalBoolean("defaultGridColor", DefaultGridColor, true);
                c.SetOptionalBoolean("showWhiteSpace", WhiteSpaceVisible, true);
                c.SetOptionalEnum("view", _viewType, SheetViewType.Normal);
                c.SetOptionalInteger("zoomScale", ZoomScale, 100);
                c.SetOptionalInteger("zoomScaleNormal", ZoomScaleNormal, 0);
                c.SetOptionalInteger("zoomScaleSheetLayoutView", _zoomScaleSheetLayoutView, 0);
                c.SetOptionalInteger("zoomScalePageLayoutView", _zoomScalePageLayoutView, 0);
                c.SetInteger("workbookViewId", _workbookViewId);
                WriteTopLeft(c);
                c.WriteOptionalElement(_pane);
                if (_selection != null || activeCell != null)
                {
                    InternalSelection s = new InternalSelection();
                    if (activeCell != null)
                        s.ActiveCell = activeCell.Value.Label;
                    else if (Selection != null)
                        s.ActiveCell = Selection.TopLeftCell.Label;
                    if (Selection != null)
                        s.Selection = _selection.LabelForSelection;
                    c.WriteOptionalElement(s);
                }
                c.WriteOptionalElement(_pivotSelection);
                c.WriteOptionalElement(Extension);
            }
        }

        internal virtual void WriteTopLeft(WriteContext c) { }

        #endregion
    }
}
